package com.leesche.netdoll.communication.protocol.encoder;

import java.util.HashMap;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.leesche.framework.core.configuration.ConfigurationUtil;
import com.leesche.framework.core.json.GsonUtil;
import com.leesche.framework.core.lang.StringUtil;
import com.leesche.framework.core.lang.UncheckedException;

public class EncoderManager {

	private static final Logger logger = LogManager.getLogger(EncoderManager.class);

	private final Map<String, Encoder> encoders = new HashMap<>();

	private volatile static EncoderManager instance;

	public static EncoderManager newInstance() {
		if (instance == null) {
			synchronized (EncoderManager.class) {
				if (instance == null)
					instance = new EncoderManager();
			}
		}
		return instance;
	}

	public Encoder encoder(String name) {
		if (!encoders.containsKey(name)) {
			logger.info("try to get an non-exist encoder with id '{}'.", name);
			return null;
		}

		return encoders.get(name);
	}

	private EncoderManager() {
		initEncoder();
	}

	private void initEncoder() {
		logger.info("initializing encoders...");

		Map<String, String> encoderConfs = GsonUtil.toMap(ConfigurationUtil.locateFromClasspath("encoder.json"), String.class, String.class);

		if (encoderConfs != null && encoderConfs.size() > 0) {
			for (String key : encoderConfs.keySet()) {
				String clazz = encoderConfs.get(key);

				if (StringUtil.isNotBlank(clazz)) {
					try {
						encoders.put(key, (Encoder) Class.forName(clazz).newInstance());

						logger.info("Encoder '{}' is initialized with '{}'.", key, clazz);

					} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
						throw new UncheckedException("failed to create encoder for \"{0}\".", e, clazz);
					}
				}
			}
		}

		logger.info("initializing encoders...OK");

	}
}
